import 'package:flutter/material.dart';
import 'package:flutter_demo/pages/base/checkbox_page.dart';
import 'package:flutter_demo/pages/base/radio_page.dart';
import 'package:flutter_demo/pages/page_with_title.dart';

import '../../utils/widget_state_property.dart';
import '../../widgets/app_widgets.dart';
import '../advanced/segmented_button_page.dart';

class ButtonPage extends PageWithTitle {
  const ButtonPage({super.key})
      : super("按钮(TextButton、OutlineButton、FilledButton、ElevatedButton)");

  @override
  List<Widget> buildContentWidgets(BuildContext context) {
    return const [
      PrimaryTitle("简介"),
      BodyText("与当前流行的前端框架Element plus类似，Flutter提供的按钮也有多种类型，他们"
          "有共同的基类ButtonStyleButton"),
      NoticeText("Flutter提供了一些按钮组，参考："),
      PageLink(RadioPage()),
      PageLink(CheckboxPage()),
      PageLink(SegmentedButtonPage()),
      AppSpacer.large,
      UlItem("ButtonStyleButton"),
      BodyText("样式按钮基类，它封装了样式加载并应用到组件构建，Flutter为其实现了以下四种类型"
          "按钮类"),
      CategoryTitle("样式"),
      LabelText("该类提供了themeStyleOf、defaultStyleOf两个方法供子类实现样式获取，在查"
          "找具体样式属性时遵循优先级widget.style>themeStyle>defaultStyle，该属性在优先"
          "级高的样式中查找不到时就会往低优先级的样式中寻找"),
      AppSpacer.normal,
      BodyText("一般我们遵循以下逻辑进行样式定义:"),
      PrimaryHeaderLabelText(
          "App统一风格的按钮样式", "我们直接在主题中配置对应类型的按钮样式(xxxButtonTheme.style)"),
      PrimaryHeaderLabelText(
          "基于主题按钮样式进行简单修改并设置到style属性",
          "通过Theme.of(context).xxxButtonTheme.style获取"
              "主题按钮样式，调用copy方法修改部分属性"),
      NoticeText("注意：因为按钮有焦点、按下、启用...等多种组件状态，所以很多属性是"
          "WidgetStateProperty对象，它可以根据当前的状态列表获取对应的属性，比如文本样式我们"
          "可以通过WidgetStateTextStyle.resolveWith构造一个新的文本样式，在回调中根据我们"
          "需要的状态集合返回自定义样式，其它情况可以通过主题按钮样式的"
          "textStyle.resolve(states)来获取统一配置的样式，这样就可以实现在主题按钮样式上自"
          "定义部分属性。"),
      PrimaryHeaderLabelText(
          "完全自定义样式设置到style属性",
          "显然我们可以直接通过ButtonStyle来自定义，这一般在部分页面独有按钮样式上使用。所有"
              "状态使用同种样式的话也有一些简便的构造方式，比如TextButton.styleFrom"),
      CategoryTitle("事件"),
      PrimaryHeaderLabelText("onPressed", "点击(按下后松开)"),
      PrimaryHeaderLabelText("onLongPress", "长按(按下一段时间后松开)"),
      PrimaryHeaderLabelText("onHover", "鼠标悬停(桌面端的)"),
      PrimaryHeaderLabelText("onFocusChange", "焦点状态改变"),
      PrimaryHeaderLabelText("focusNode", "焦点控制"),
      PrimaryHeaderLabelText("autofocus", "自动获取焦点"),
      PrimaryHeaderLabelText(
          "statesController",
          "用于更新状态，像selected、disabled、error这些状态一般是我们手动设置的，而其他的"
              "状态一般跟事件有关系，由事件触发自动修改"),
      AppSpacer.large,
      _TextButtonExample(),
      OlItem(1, "TextButton"),
      BodyText("文本按钮，纯粹的文本不加任何装饰物"),
      LabelText("在主题中通过textButtonTheme属性配置统一风格的文本按钮"),
      NoticeText("我原本以为只要在状态控制器中设置为错误状态，文本颜色就会变成红色，实际不行，"
          "它的文本颜色并非来自主题中配置的error颜色，也不是来自buttonStyle.textStyle"
          ".color，而是来自buttonStyle.foregroundColor。查看源码可以看到在构建按钮组件时"
          "，它对textStyle的color属性修改为foregroundColor的值，真是意想不到，配置主题是"
          "需多加留意。。。"),
      AppSpacer.large,
      _OutlineButtonExample(),
      OlItem(2, "OutlineButton"),
      BodyText("外边框按钮，对比文本按钮多了外边框，但默认是outline颜色，好像多数ui设计会使用"
          "主题色作为边框？可以通过style.side自定义边框颜色"),
      AppSpacer.large,
      _FilledButtonExample(),
      OlItem(3, "FilledButton"),
      BodyText("填充按钮，默认背景使用主要颜色（primary），默认文本使用onPrimary"),
      AppSpacer.large,
      _ElevatedButtonExample(),
      OlItem(4, "ElevatedButton"),
      BodyText("升高按钮，样式就是一个Card+Text，在Material3中使用surfaceContainerLow"
          "背景+primary文本颜色。"),
      LabelText("这里根据按压状态不同设置了不同的海拔，似乎有些过渡效果，还想说效果不行的话使用"
          "其它方案，比如监听控制器按压状态变化用AnimatedBuilder来实现动态修改海拔，或者使用"
          "AnimatedPhysicalModel+Text来实现也有不错的动画效果，但它本身支持的话就可以通过"
          "主题来配置这种按压动画了。")
    ];
  }
}

void _showSnackBar(BuildContext context, String text) {
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(
      content: Text(text),
    ),
  );
}

class _TextButtonExample extends StatelessWidget {
  const _TextButtonExample();

  @override
  Widget build(BuildContext context) {
    return Wrap(
      children: [
        TextButton(
          onPressed: () {
            _showSnackBar(context, "点击文本按钮");
          },
          child: const Text("文本按钮（默认primary）"),
        ),
        TextButton(
          onPressed: () {},
          statesController: WidgetStatesController({WidgetState.error}),
          style: ButtonStyle(
            foregroundColor: WidgetStatePropertySingle(
                error: Theme.of(context).colorScheme.error),
          ),
          child: const Text("错误状态"),
        ),
      ],
    );
  }
}

class _OutlineButtonExample extends StatelessWidget {
  const _OutlineButtonExample();

  @override
  Widget build(BuildContext context) {
    return Wrap(
      children: [
        OutlinedButton(
          onPressed: () {
            _showSnackBar(context, "点击边框按钮");
          },
          child: const Text("边框按钮"),
        ),
        AppSpacer.mini,
        OutlinedButton(
          onPressed: () {
            _showSnackBar(context, "点击边框按钮");
          },
          style: ButtonStyle(
            side: WidgetStatePropertyAll(
              //这里懒得写了，所有状态返回主题色边框
              BorderSide(color: Theme.of(context).colorScheme.primary),
            ),
          ),
          child: const Text("自定义边框"),
        ),
      ],
    );
  }
}

class _FilledButtonExample extends StatelessWidget {
  const _FilledButtonExample();

  @override
  Widget build(BuildContext context) {
    return Wrap(
      children: [
        FilledButton(
          onPressed: () {
            _showSnackBar(context, "点击填充按钮");
          },
          child: const Text("填充按钮"),
        ),
      ],
    );
  }
}

class _PressElevated implements WidgetStateProperty<double?> {
  const _PressElevated(this._pressed, this._unpressed);

  final double? _pressed;
  final double? _unpressed;

  @override
  double? resolve(Set<WidgetState> states) {
    return states.contains(WidgetState.pressed) ? _pressed : _unpressed;
  }
}

class _ElevatedButtonExample extends StatelessWidget {
  const _ElevatedButtonExample();

  @override
  Widget build(BuildContext context) {
    return Wrap(
      children: [
        ElevatedButton(
          onPressed: () {
            _showSnackBar(context, "点击升高按钮");
          },
          style: const ButtonStyle(elevation: _PressElevated(0, 5)),
          child: const Text("升高按钮"),
        ),
      ],
    );
  }
}
